package engine;

import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 *
 * @author LiZichen
 */
public class XPathQueryEngine {
   
    private Document parsedXML ;

    public XPathQueryEngine(String filePath) throws ParserConfigurationException, SAXException, IOException{
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance() ;
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        parsedXML = builder.parse(filePath) ;
       
    }

    public Object query(String query) throws XPathExpressionException{
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath() ;
        XPathExpression expr = xpath.compile(query) ;

        Object result = expr.evaluate(parsedXML, XPathConstants.NODESET);

        return result ;


    }

    public String printResult(Object result){
        String ret="" ;
        NodeList resultNodes = (NodeList) result ;
        ret = printHelper(resultNodes) ;
     
        return ret ;
    }

    private String printHelper(NodeList nodes){
        String ret="" ;
        for (int i=0 ; i<nodes.getLength() ; i++){
            Node curr = nodes.item(i) ;
            ret += printNodeHelper(curr) + "\n";


        }
        return ret ;
    }

    private String printNodeHelper(Node node){
        String ret = "" ;
        if (node.getNodeType()==3) ret = node.getNodeValue();
            else {
            	
                ret += "<"+node.getNodeName() ;
                
                if (node.getAttributes()!=null){
            		NamedNodeMap attributes = node.getAttributes();
            		for (int i=0 ; i<node.getAttributes().getLength() ; i++){
            			ret += " "+attributes.item(i).getNodeName();
            			ret += " = '"+attributes.item(i).getTextContent()+"'";
            		}
            	}
                ret += ">" ;
                if (node.getChildNodes().getLength()!=0){
                    for (int i=0 ; i<node.getChildNodes().getLength() ; i++){
                        ret += printNodeHelper(node.getChildNodes().item(i)) ;
                        
                    }
                    ret +=  "<\\"+node.getNodeName()+">";
                }
            }
        return ret ;
    }

}
